package com.afollestad.dragselectrecyclerview.slice;

import com.afollestad.dragselectrecyclerview.ResourceTable;
import com.afollestad.dragselectrecyclerview.bean.DragSelectItem;
import com.afollestad.library.callback.DragSelectTouchListener;
import com.afollestad.library.component.MyListContainer;
import com.afollestad.dragselectrecyclerview.adapter.GridProvider;
import com.afollestad.library.utils.MyUtils;
import com.afollestad.library.utils.PixelUtil;
import com.afollestad.library.utils.ToastUtil;

import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;

import ohos.agp.animation.AnimatorProperty;
import ohos.agp.components.DirectionalLayout;
import ohos.agp.components.Text;
import ohos.agp.components.Image;
import ohos.agp.components.Component;
import ohos.agp.components.TableLayoutManager;
import ohos.agp.components.element.PixelMapElement;

import ohos.data.DatabaseHelper;
import ohos.data.preferences.Preferences;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.eventhandler.InnerEvent;
import ohos.global.resource.NotExistException;
import ohos.multimodalinput.event.TouchEvent;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * MainAbilitySlice
 *
 * @since 2021-03-12
 */
public class MainAbilitySlice extends AbilitySlice {
    private static final String SELECT_MODE = "select_mode";

    private static final int ANIMATOR_DURATION = 200;

    private static final int SHOW_MENU = 100;

    private static final int HIDE_MENU = 200;

    private MyListContainer list;
    private GridProvider gridProvider;
    private DragSelectTouchListener dragSelectTouchListener;
    private DirectionalLayout titleLayout;
    private Text cancelButton;
    private Text titleText;
    private Text confirmButton;
    private Text menuButton;
    private Preferences preferences;
    private int currentMode;
    private Image rangeImage;
    private Image pathImage;
    private DirectionalLayout menuLayout;
    private DirectionalLayout rangeButton;
    private DirectionalLayout pathButton;
    private Component clickToCloseMenuLayout;
    private AnimatorProperty menuLayoutHideAnimator;
    private AnimatorProperty menuLayoutShowAnimator;

    private final List<DragSelectItem> array = new ArrayList<>();

    private final MyEventHandler handler = new MyEventHandler(EventRunner.getMainEventRunner());

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_main);
        processData();
        initView();
        initData();
    }

    /**
     * 初始化各component
     */
    private void initView() {
        if (findComponentById(ResourceTable.Id_list) instanceof MyListContainer) {
            list = (MyListContainer) findComponentById(ResourceTable.Id_list);
        }
        if (findComponentById(ResourceTable.Id_dl_title) instanceof DirectionalLayout) {
            titleLayout = (DirectionalLayout) findComponentById(ResourceTable.Id_dl_title);
        }
        if (findComponentById(ResourceTable.Id_cancel_button) instanceof Text) {
            cancelButton = (Text) findComponentById(ResourceTable.Id_cancel_button);
        }
        if (findComponentById(ResourceTable.Id_title_tv) instanceof Text) {
            titleText = (Text) findComponentById(ResourceTable.Id_title_tv);
        }
        if (findComponentById(ResourceTable.Id_confirm_button) instanceof Text) {
            confirmButton = (Text) findComponentById(ResourceTable.Id_confirm_button);
        }
        if (findComponentById(ResourceTable.Id_menu_button) instanceof Text) {
            menuButton = (Text) findComponentById(ResourceTable.Id_menu_button);
        }
        DatabaseHelper databaseHelper = new DatabaseHelper(this);
        preferences = databaseHelper.getPreferences("select_mode");

        if (findComponentById(ResourceTable.Id_menu_layout) instanceof DirectionalLayout) {
            menuLayout = (DirectionalLayout) findComponentById(ResourceTable.Id_menu_layout);
        }
        if (findComponentById(ResourceTable.Id_range_button) instanceof DirectionalLayout) {
            rangeButton = (DirectionalLayout) findComponentById(ResourceTable.Id_range_button);
        }
        if (findComponentById(ResourceTable.Id_path_button) instanceof DirectionalLayout) {
            pathButton = (DirectionalLayout) findComponentById(ResourceTable.Id_path_button);
        }
        if (findComponentById(ResourceTable.Id_ig_range) instanceof Image) {
            rangeImage = (Image) findComponentById(ResourceTable.Id_ig_range);
        }
        if (findComponentById(ResourceTable.Id_ig_path) instanceof Image) {
            pathImage = (Image) findComponentById(ResourceTable.Id_ig_path);
        }
        clickToCloseMenuLayout = findComponentById(ResourceTable.Id_bg_component);

        initAnimator();
    }

    private void initAnimator() {
        // 设置menu消失的动画
        menuLayoutHideAnimator = menuLayout.createAnimatorProperty();
        menuLayoutHideAnimator.alpha(0).setDuration(ANIMATOR_DURATION);
        // 设置menu显示的动画
        int offsetY = 33;
        menuLayoutShowAnimator = menuLayout.createAnimatorProperty();
        menuLayoutShowAnimator
                .moveFromX(PixelUtil.screenWidth()).moveToX((PixelUtil.screenWidth()) - (menuLayout.getWidth()))
                .moveFromY(-(menuLayout.getHeight() + offsetY)).moveToY(offsetY)
                .scaleXFrom(0).scaleX(1)
                .scaleYFrom(0).scaleY(1)
                .alphaFrom(0).alpha(1)
                .setDuration(ANIMATOR_DURATION);
    }

    /**
     * 初始化数据
     */
    private void initData() {
        initProviderAndList();
        // 获取选中模式
        currentMode = preferences.getInt(SELECT_MODE, -1);
        if (currentMode == 1) {
            dragSelectTouchListener.setMode(DragSelectTouchListener.Mode.PATH);
        } else {
            dragSelectTouchListener.setMode(DragSelectTouchListener.Mode.RANGE);
        }

        menuButton.setClickedListener(component -> setMenuLayoutVisible(true));

        clickToCloseMenuLayout.setTouchEventListener((component, touchEvent) -> {
            if (menuLayout.getVisibility() != Component.HIDE) {
                if (touchEvent.getAction() == TouchEvent.PRIMARY_POINT_UP) {
                    setMenuLayoutVisible(false);
                }
                return true;
            }
            return false;
        });

        // 设置点击事件
        rangeButton.setClickedListener(view -> {
            if (currentMode != 0) {
                // 选中range模式
                currentMode = 0;
                try {
                    shiftSelectMode(currentMode);
                } catch (IOException | NotExistException e) {
                    e.printStackTrace();
                }
            }
            setMenuLayoutVisible(false);
        });
        setPtahBtnClick();

        setCanCelBtnClick();

        setConfirmBtnClick();
    }

    private void initProviderAndList() {
        // 初始化ListProvider
        gridProvider = new GridProvider(this);
        gridProvider.setDataList(array);
        gridProvider.setOnItemSelectChangeListener((selected) -> {
            if (selected > 0) {
                titleLayout.setVisibility(Component.VISIBLE);
                titleText.setText("Selection (" + selected + ")");
            } else {
                titleLayout.setVisibility(Component.HIDE);
            }
        });
        TableLayoutManager layoutManager = new TableLayoutManager();
        layoutManager.setColumnCount(3);
        list.setLayoutManager(layoutManager);
        list.setItemProvider(gridProvider);
        dragSelectTouchListener = DragSelectTouchListener.create(list);
        list.addDragSelectTouchListener(dragSelectTouchListener);
        try {
            shiftSelectMode(currentMode);
        } catch (IOException | NotExistException e) {
            e.printStackTrace();
        }
    }

    private void setPtahBtnClick() {
        // 设置点击事件
        pathButton.setClickedListener(view -> {
            if (currentMode != 1) {
                // 选中path模式
                currentMode = 1;
                try {
                    shiftSelectMode(currentMode);
                } catch (IOException | NotExistException e) {
                    e.printStackTrace();
                }
            }
            setMenuLayoutVisible(false);
        });
    }

    private void setCanCelBtnClick() {
        // 取消按钮点击事件
        cancelButton.setClickedListener((view) -> {
            List<DragSelectItem> dataList = gridProvider.getDataList();
            if (!MyUtils.isListNoElement(dataList)) {
                // 遍历所有数据并清空选中状态
                for (DragSelectItem item : dataList) {
                    item.setSelect(false);
                }
            }
            // 刷新数据
            gridProvider.notifyDataChanged();
            // 隐藏头部选中个数布局
            titleText.setText("");
            titleLayout.setVisibility(Component.HIDE);
        });
    }

    private void setConfirmBtnClick() {
        // 确定按钮点击事件
        confirmButton.setClickedListener((view) -> {
            List<DragSelectItem> dataList = gridProvider.getDataList();
            StringBuilder string = new StringBuilder("selected letters :");
            // 遍历所有数据并获得选中item的position
            for (int i = 0; i < dataList.size(); i++) {
                DragSelectItem item = dataList.get(i);
                if (item.isSelect()) {
                    string.append(" ").append(i);
                    item.setSelect(false);
                }
            }
            // 刷新数据
            gridProvider.notifyDataChanged();
            // 隐藏头部选中个数布局
            titleText.setText("");
            titleLayout.setVisibility(Component.HIDE);
            ToastUtil.showShort(this, string.toString());
        });
    }

    /**
     * 设置菜单栏显示/隐藏
     *
     * @param visible 菜单栏是否可见
     */
    private void setMenuLayoutVisible(boolean visible) {
        if (visible) {
            handler.sendEvent(SHOW_MENU);
            menuLayout.invalidate();
            menuLayoutShowAnimator.start();
        } else {
            gridProvider.setMenuShow(false);
            menuLayoutHideAnimator.start();
            handler.sendEvent(HIDE_MENU, ANIMATOR_DURATION);
        }
    }

    /**
     * 切换选择模式
     *
     * @param mode 选中模式
     * @throws IOException       IOException
     * @throws NotExistException NotExistException
     */
    private void shiftSelectMode(int mode) throws IOException, NotExistException {
        if (mode == 1) {
            dragSelectTouchListener.setMode(DragSelectTouchListener.Mode.PATH);
            PixelMapElement pixelMapElement =
                    new PixelMapElement(getResourceManager().getResource(ResourceTable.Media_uncheck));
            rangeImage.setBackground(pixelMapElement);
            pixelMapElement = new PixelMapElement(getResourceManager().getResource(ResourceTable.Media_check));
            pathImage.setBackground(pixelMapElement);
        } else {
            dragSelectTouchListener.setMode(DragSelectTouchListener.Mode.RANGE);
            PixelMapElement pixelMapElement =
                    new PixelMapElement(getResourceManager().getResource(ResourceTable.Media_check));
            rangeImage.setBackground(pixelMapElement);
            pixelMapElement = new PixelMapElement(getResourceManager().getResource(ResourceTable.Media_uncheck));
            pathImage.setBackground(pixelMapElement);
        }
        // 保存selectMode至本地
        preferences.putInt(SELECT_MODE, mode);
        preferences.flush();
    }

    // 处理后获得list数据
    private void processData() {
        String data = "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z";
        String[] array = data.split(" ");
        for (int a = 0; a < array.length; a++) {
            this.array.add(new DragSelectItem(array[a], colors[a]));
        }
    }

    private final String[] colors = {
            "#F44336ff", "#E91E63ff", "#9C27B0ff", "#673AB7ff", "#3F51B5ff", "#2196F3ff",
            "#03A9F4ff", "#00BCD4ff", "#009688ff", "#4CAF50ff", "#8BC34Aff", "#CDDC39ff",
            "#FFEB3Bff", "#FFC107ff", "#FF9800ff", "#FF5722ff", "#795548ff", "#9E9E9Eff",
            "#607D8Bff", "#F44336ff", "#E91E63ff", "#9C27B0ff", "#673AB7ff", "#3F51B5ff",
            "#2196F3ff", "#03A9F4ff"
    };

    @Override
    public void onForeground(Intent intent) {
        super.onForeground(intent);
    }

    @Override
    protected void onStop() {
        super.onStop();
        if (menuLayoutHideAnimator != null) {
            menuLayoutHideAnimator.release();
        }
        if (menuLayoutShowAnimator != null) {
            menuLayoutShowAnimator.release();
        }
    }

    @Override
    protected void onBackPressed() {
        if (menuLayout.getVisibility() == Component.VISIBLE) {
            setMenuLayoutVisible(false);
            return;
        }
        if (titleLayout.getVisibility() == Component.VISIBLE) {
            cancelButton.callOnClick();
            return;
        }
        super.onBackPressed();
    }

    private class MyEventHandler extends EventHandler {
        private MyEventHandler(EventRunner runner) {
            super(runner);
        }

        // 重写实现processEvent方法
        @Override
        public void processEvent(InnerEvent event) {
            super.processEvent(event);
            switch (event.eventId) {
                case SHOW_MENU:
                    // 显示菜单栏
                    if (menuLayout != null && clickToCloseMenuLayout != null && gridProvider != null) {
                        menuLayout.setVisibility(Component.VISIBLE);
                        clickToCloseMenuLayout.setVisibility(Component.VISIBLE);
                        gridProvider.setMenuShow(true);
                        menuLayout.scrollTo(100, 100);
                    }
                    break;
                case HIDE_MENU:
                    // 隐藏菜单栏
                    if (menuLayout != null && clickToCloseMenuLayout != null && gridProvider != null) {
                        menuLayout.setVisibility(Component.HIDE);
                        clickToCloseMenuLayout.setVisibility(Component.HIDE);
                    }
                    break;
            }
        }
    }

}
